//
// Created by 原帅 on 2021/2/10.
//

#ifndef IVENGINE_IERUNLOOP_H
#define IVENGINE_IERUNLOOP_H

#include "IERunLoopInterface.h"
#include <vector>
#include <queue>
using namespace std;

class IERunLoop {
private:
    explicit IERunLoop();
    virtual ~IERunLoop();

    static IERunLoop *ieRunLoop;
    vector<IERunLoopInterface*> inits;
    vector<IERunLoopInterface*> tasks;
    vector<IERunLoopInterface*> beforeTasks;
    vector<IERunLoopInterface*> afterTasks;
    queue<IERunLoopInterface*> onceTasks;
    queue<IERunLoopInterface*> onceTasksBeforeRunloop;
    queue<IERunLoopInterface*> onceTasksAfterRunloop;

    bool runing;
    unsigned long interval;

public:
    unsigned long getInterval() const;
    void setInterval(unsigned long interval);
    static IERunLoop* Singleton();
    int runloop();
    void stopRunloop();
    void addInits(IERunLoopInterface* anInterface);
    void addTask(IERunLoopInterface* interface);
    void insertTask(int index, IERunLoopInterface* anInterface);
    void addTaskBefore(IERunLoopInterface* anInterface);
    void insertTaskBefore(int index,IERunLoopInterface* anInterface);
    void addTaskAfter(IERunLoopInterface* anInterface);
    void insertTaskAfter(int index,IERunLoopInterface* anInterface);
    void pushOnceTask(IERunLoopInterface* anInterface);
    void pushOnceTaskOnBefore(IERunLoopInterface* anInterface);
    void pushOnceTaskOnAfter(IERunLoopInterface* anInterface);
    void removeTaskFromAllRunloop(IERunLoopInterface* anInterface);
    void removeTaskFromRunloop(IERunLoopInterface* anInterface,vector<IERunLoopInterface*> tasks);
private:
    void runloopRepeat(vector<IERunLoopInterface*> &tasks);
    void runloopOnce(queue<IERunLoopInterface*> &tasks);
};


#endif //IVENGINE_IERUNLOOP_H
